package cn.master.volley.models.response.listener;

import android.os.Message;
import android.util.Log;

import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.fasterxml.jackson.databind.JsonMappingException;

import cn.master.volley.commons.CustomHeaderRequest.IsCacheListener;
import cn.master.volley.models.pojo.Wrapper;
import cn.master.volley.models.response.handler.ResponseHandler;

/**
 * 监听返回信息，统一处理错误信息
 *
 * @param <T> 一个与 {@link Wrapper#getData()} 数据结构匹配的数据实体类，由调用者指定
 */
public class ResponseListener<T> implements IsCacheListener<String>, Listener<String>, ErrorListener {

    private static final String TAG = ResponseListener.class.getSimpleName();

    private ResponseHandler mHandler = null;
    private ResolveJson<T> mJsonInterface = null;

    /**
     * 构造方法
     *
     * @param handler
     * @param jsonInterface 数据解析接口 , 如果该对象为 null , 则 {@link ResponseListener#mJsonInterface} 的默认实现为 {@link JsonHelper#json2String} ,
     *                      {@link ResponseListener} 类的泛型类型为  {@link String} ,
     *                      并且 {@link ResponseListener#succeed(Message, Object)} 可转变为 {@link ResponseListener#succeed(Message, String)}
     */
    public ResponseListener(ResponseHandler handler, ResolveJson<T> jsonInterface) {
        this.mHandler = handler;
        this.mJsonInterface = jsonInterface;
    }

    /**
     * 构造方法
     *
     * @param handler </br>数据解析时，{@link ResponseListener#mJsonInterface} 的默认实现为 {@link JsonHelper#json2String} ,
     *                {@link ResponseListener} 类的泛型类型为  {@link String} ,
     *                并且 {@link ResponseListener#succeed(Message, Object)} 可转变为 {@link ResponseListener#succeed(Message, String)}
     */
    public ResponseListener(ResponseHandler handler) {
        this.mHandler = handler;
    }

    /**
     * MyVolley中使用的监听方法
     */
    @Override
    public void onResponse(final String response) {
        onResponse(false, response);
    }

    @Override
    public void onResponse(final boolean isCache, final String response) {
        if (mHandler == null) {
            return;
        }
        //开启线程用来处理数据
        new Thread(new Runnable() {
            @Override
            public void run() {
                dataProcessing(isCache, response);
            }
        }).start();
    }

    /**
     * 数据处理（Json解析及数据分发）
     *
     * @param response
     */
    @SuppressWarnings("unchecked")
    private void dataProcessing(boolean isCache, String response) {
        try {
            Wrapper<T> wrapper = null;
            if (mJsonInterface == null) {
                mJsonInterface = (ResolveJson<T>) ResolveJsonHelper.resolveJson2String;
            }
            try {
                wrapper = mJsonInterface.resolve(response);
            } catch (JsonMappingException e) {
                e.printStackTrace();
                mJsonInterface = (ResolveJson<T>) ResolveJsonHelper.resolveJson2String;
                wrapper = mJsonInterface.resolve(response);
            }
            Message msg = new Message();
            if (wrapper.getCode() != Wrapper.SUCCESS) {

                // Token无效，说明没有登陆或Token已经过期
                if (wrapper.getCode() == Wrapper.TOKEN_INVALID) {
                    msg.what = ResponseHandler.INVALID_USER;
                } else {
                    msg.what = ResponseHandler.FAIL;
                }
                msg.arg1 = wrapper.getCode();
                msg.obj = wrapper.getData();
                Log.e(TAG,response);
                mHandler.sendMessage(msg);
                return;
            }
            msg.what = ResponseHandler.SUCCEED;
            msg.obj = wrapper.getData();
            //arg1 参数用来存储是否为缓存数据
            msg.arg1 = isCache ? 1 : 0;
            succeed(msg, wrapper.getData());
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, response);
            mHandler.sendEmptyMessage(ResponseHandler.ERROR);
        }
    }

    @Override
    public void onErrorResponse(VolleyError error) {
        if (mHandler == null) {
            return;
        }
        if (error != null && error.networkResponse != null)
            Log.e(TAG, "Network request failed ==> " + "networkResponse.statusCode=" + error.networkResponse.statusCode + "\n" + "networkResponse.data=" + new String(error.networkResponse.data) + "\n" + error.getMessage() + "\n" + Log.getStackTraceString(new Throwable()));
        mHandler.sendEmptyMessage(ResponseHandler.CONNECTION_EXCPTION);
    }

    /**
     * 该方法由异步线程调用执行，负责给主线程的 Handler 发送成功消息。</br>
     * 子类可重写此方法，可更改 message 中的数据（数据重组）或进行其它的数据处理
     *
     * @param message 该  message 已包含了需要返回的成功码及  data 数据
     * @param t       一个与 {@link Wrapper#getData()} 数据结构匹配的数据实体类，由调用者指定
     * @return
     */
    public void succeed(Message message, T t) {
        mHandler.sendMessage(message);
    }

}

